//
//  UIImage+Filter.m
//  KKShopping
//
//  Created by Albert Lee on 8/1/13.
//  Copyright (c) 2013 KiDulty. All rights reserved.
//

#import "UIImage+Filter.h"
#include <math.h>

typedef unsigned char Quantum;
typedef double MagickRealType;

#define RoundToQuantum(quantum)  ClampToQuantum(quantum)
#define ScaleCharToQuantum(value)  ((Quantum) (value))
#define SigmaGaussian  ScaleCharToQuantum(4)
#define TauGaussian  ScaleCharToQuantum(20)
#define QuantumRange  ((Quantum) 65535)

/* These are our own constants */
#define SAFECOLOR(color) MIN(255,MAX(0,color))

typedef void (*FilterCallback)(UInt8 *pixelBuf, UInt32 offset, void *context);
typedef void (*FilterBlendCallback)(UInt8 *pixelBuf, UInt8 *pixelBlendBuf, UInt32 offset, void *context);
@implementation UIImage (Filter)

- (UIImage *)orginFilterWithCIContext:(CIContext *)context{
    //do nothing 
    return self;
}

- (UIImage*) vignetteFilterWithCIContext:(CIContext *)context{
  CIImage * beginImage = [CIImage imageWithCGImage:self.CGImage];
    CIFilter *filterG = [CIFilter filterWithName:@"CIScreenBlendMode"  //蓝色底儿
                                   keysAndValues: kCIInputImageKey, beginImage,
                         @"inputBackgroundImage", [CIImage imageWithColor:[CIColor colorWithRed:255.0/255.0
                                                                                          green:255.0/255.0
                                                                                           blue:255
                                                                                          alpha:0.01]], nil];
    CIImage *outputImageG = [filterG outputImage];
    
    CIFilter *filterH = [CIFilter filterWithName:@"CIToneCurve"  //色调曲线
                                   keysAndValues: kCIInputImageKey, outputImageG,
                         @"inputPoint0", [CIVector vectorWithX:0.0 Y:0.0],
                         @"inputPoint1", [CIVector vectorWithX:63.0/255.0 Y:95.0/255.0],
                         @"inputPoint2", [CIVector vectorWithX:81.0/255.0 Y:153.0/255.0],
                         @"inputPoint3", [CIVector vectorWithX:135.0/255.0 Y:210.0/255.0],
                         @"inputPoint4", [CIVector vectorWithX:1 Y:1],nil];
    CIImage *outputImageH = [filterH outputImage];
    
    CIFilter *gammaFilter = [CIFilter filterWithName:@"CIGammaAdjust"    //加黑色蒙层
                                       keysAndValues: kCIInputImageKey, outputImageH,
                             @"inputPower", @1.5f, nil];
    CIImage *outputImageGamma = [gammaFilter outputImage];
    
    CGImageRef cgimg = [context createCGImage:outputImageGamma fromRect:[beginImage extent]];
    UIImage *newImage = [UIImage imageWithCGImage:cgimg];
    CGImageRelease(cgimg);
    return newImage;

}

- (UIImage *)test:(CIContext *)test{
      CIImage * beginImage = [CIImage imageWithCGImage:self.CGImage];
    CIFilter *filterG = [CIFilter filterWithName:@"CIGloom"];  //蓝色底儿
    [filterG setValue:beginImage forKey:kCIInputImageKey];
                         
    CIImage *outputImageG = [filterG outputImage];
    
    CIFilter *filterOther = [CIFilter filterWithName:@"CIGloom"];
    [filterOther setValue:outputImageG forKey:kCIInputImageKey];
    CIImage *outputImageGG = [filterOther outputImage];
    CGImageRef cgimg = [test createCGImage:outputImageGG fromRect:[outputImageG extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg];
    CGImageRelease(cgimg);
    return newImg;
}

- (UIImage *)Unreal:(CIContext *)test{
    CIImage * beginImage = [CIImage imageWithCGImage:self.CGImage];
    CIFilter *filterG = [CIFilter filterWithName:@"CIGloom"];  //蓝色底儿
    [filterG setValue:beginImage forKey:kCIInputImageKey];
    
    CIImage *outputImageH = [filterG outputImage];
    
    CIFilter *gammaFilter = [CIFilter filterWithName:@"CIGammaAdjust"    //加黑色蒙层
                                       keysAndValues: kCIInputImageKey, outputImageH,
                             @"inputPower", @0.75f, nil];
    CIImage *outputImageGamma = [gammaFilter outputImage];
    
    CGImageRef cgimg = [test createCGImage:outputImageGamma fromRect:[outputImageH extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg];
    CGImageRelease(cgimg);
    return newImg;
    return newImg;
}


- (void)setFilterAttributeByFilter:(CIFilter *)fliter{
    NSDictionary *dic = [fliter attributes];
    NSArray *keys = [dic allKeys];
    NSMutableArray *attributesArray = [NSMutableArray array];
    for(int i=0;i<keys.count;i++){
        NSDictionary *subdic  = [dic objectForKey:[keys objectAtIndex:i]];
        if(![subdic isKindOfClass:[NSDictionary class]]){
            continue;
        }
        NSArray *subkeys = [subdic allKeys];
        for(int j=0;j<subkeys.count; j++){
            NSString *value = [subdic objectForKey:@"CIAttributeClass"];
            if([value isKindOfClass:[NSString class]]&&[value isEqualToString:@"NSNumber"]){
                float minnum = [[subdic objectForKey:@"CIAttributeSliderMin"] floatValue];
                float maxnum = [[subdic objectForKey:@"CIAttributeSliderMax"] floatValue];
                if(minnum!=maxnum){
                    float slideValue       = (maxnum +minnum)/2;
                    [fliter setValue:[NSNumber numberWithFloat:slideValue] forKey:[keys objectAtIndex:i]];
                    [attributesArray addObject:[NSString stringWithFormat:@"%@+%f",[keys objectAtIndex:i],slideValue]];
                }
                
                break;
                
            }
        }
        
    }
    
//    if(attributesArray.count>0){
//        NSString *filterAttrbuteString = [attributesArray lastObject];
//        NSArray *array = [filterAttrbuteString componentsSeparatedByString:@"+"];
//        [fliter setValue:[NSNumber numberWithFloat:[[array objectAtIndex:1] floatValue]] forKey:[array objectAtIndex:0]];
//    }
}
- (UIImage *)filterWithName:(NSString *)filterName andCIContext:(CIContext *)context{
    CIImage * beginImage = [CIImage imageWithCGImage:self.CGImage];
    CIFilter *filter     = [CIFilter filterWithName:filterName];
    [filter setValue:beginImage forKey:kCIInputImageKey];
    [self setFilterAttributeByFilter:filter];
    CIImage *outputImage = [filter outputImage];
    CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg];
    CGImageRelease(cgimg);
    return newImg;
}

- (UIImage *)circleImage{
    int w = self.size.width;
    int h = self.size.height;
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, w, h)];
    [path closePath];
    [path fill];
    
    
    UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0);
    
    {
        CGContextRef context = UIGraphicsGetCurrentContext();
        //CGContextRotateCTM(context,M_PI);
        CGContextScaleCTM (context, 1, -1);
        CGContextTranslateCTM(context, 0,-h);
        CGContextAddPath(context, path.CGPath);
        CGContextClosePath(context);
        CGContextClip(context);
        CGContextDrawImage(context, CGRectMake(0, 0, w, h), self.CGImage);
        
    }
    
    
    
    
    UIImage *mask = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return  mask;
}

- (UIImage *)blurryImageWithLevel:(CGFloat)blur {
    CIImage *inputImage = [CIImage imageWithCGImage:self.CGImage];
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"
                                  keysAndValues:kCIInputImageKey, inputImage,
                        @"inputRadius", @(blur),
                        nil];
    
    CIImage *outputImage =inputImage;
    if (filter) {
        outputImage=filter.outputImage;
    }
    
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef outImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
    return [UIImage imageWithCGImage:outImage];
}

@end
